#ifndef MODBUS_SLAVE_HPP
#define MODBUS_SLAVE_HPP

namespace Modbus {

class Slave {
public:
    class Function {
    public:
        explicit Function(Slave *slave);
        virtual ~Function() = default;
        virtual unsigned int getFunctionCode(void) = 0;
        virtual int parse(void *pdu,unsigned int size,bool broadcast) = 0;
    protected:
        Slave *slave;
    };

    class PortableStrategy {
    public:
        virtual ~PortableStrategy() = default;
        virtual bool init() = 0;
        virtual bool deinit() = 0;
        virtual bool lock() = 0;
        virtual bool unlock() = 0;
    };

    class Result {
    public:
        static const int SUCCESS = 0;
        static const int FAILED = -1;
        static const int NO_PORTABLE_STRATEGY = -2;
        static const int NO_FUNCTION = -3;
        static const int LOCK_FAILED = -4;
        static const int UNLOCK_FAILED = -5;
        static const int PORTABLE_STRATEGY_INIT_FAILED = -6;
        static const int PORTABLE_STRATEGY_DEINIT_FAILED = -7;
        static const int FUNCTION_LIST_FULL = -8;
    };
public:
    explicit Slave(PortableStrategy *portable_strategy);
    virtual ~Slave() = default;

    virtual int open();
    virtual int close();

    virtual int addFunction(Function *function);
    virtual int removeFunction(Function *function);
    virtual int removeFunction(unsigned int function_code);

    virtual int sendResponse(void *pdu,unsigned int size) = 0;
public:
    static const int MAX_FUNCTION_COUNT = 128;
protected:
    Function *function_list[MAX_FUNCTION_COUNT] = {nullptr,};
private:
    PortableStrategy *portable_strategy = nullptr;
};

}

#endif
